package com.example.demo.thread.ch4.case02;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author: htc
 * @date: Created in 14:40 2019/1/9.
 */
public class RecordProcessor implements StatProcessor {
    private final Map<Long, DelayItem> summaryResult;
    private static final FastTimeStampParser FAST_TIME_STAMP_PARSER = new FastTimeStampParser();
    private static final DecimalFormat df = new DecimalFormat("0000");

    private static final int INDEX_TIMESTAMP = 0;
    private static final int INDEX_TRACE_ID = 0;
    private static final int INDEX_MESSAGE_TYPE = 0;
    private static final int INDEX_OPERATION_NAME = 0;
    private static final int SRC_DEVICE = 0;
    private static final int DEST_DEVICE = 0;

    public static final int FIELDS_COUNT = 11;

    private final Map<String, DelayData> immediateResult;

    private final int traceIdDiff;
    private final String expectedOperationName;
    private String selfDevice = "ESB";

    private long currRecordDate;

    /**
     * 采样周期
     */
    private final int sampleInterval;
    private final String expectedExternalDeviceList;

    public RecordProcessor(int sampleInterval, int traceIdDiff, String expectedOperationName, String expectedExternalDeviceList) {
        summaryResult = new TreeMap<Long, DelayItem>();

        this.immediateResult = new HashMap<String, DelayData>();
        this.sampleInterval = sampleInterval;
        this.traceIdDiff = traceIdDiff;
        this.expectedOperationName = expectedOperationName;
        this.expectedExternalDeviceList = expectedExternalDeviceList;
    }

    public void process(String[] recordParts) {
        String traceId;
        String matchingReqTraceId;
        String recordType;
        String interfaceName;
        String operationName;
        String timeStamp;
        String strRspTimeStamp;
        String strReqTimeStamp;
        DelayData delayData;

        traceId = recordParts[INDEX_TRACE_ID];
        recordType = recordParts[INDEX_MESSAGE_TYPE];
        timeStamp = recordParts[INDEX_TIMESTAMP];

        if ("response".equals(recordType)) {
            int nonSeqLen = traceId.length() - 4;
            String traceIdSeq = traceId.substring(nonSeqLen);

            //获取这条响应记录相应的请求记录中的traceId
            matchingReqTraceId = traceId.substring(0, nonSeqLen)
                    + df.format(Integer.valueOf(traceIdSeq).intValue()
                    - Integer.valueOf(traceIdDiff).intValue());
            delayData = immediateResult.remove(matchingReqTraceId);
            if (null == delayData) {
                //不可能到这里，除非日志记录有错误
                return;
            }

            delayData.setRspTime(timeStamp);
            strRspTimeStamp = timeStamp;
            strReqTimeStamp = delayData.getReqTime();

            //仅在读取到表示相应的请求记录时才统计数据
            long reqTimeStamp = parseTimeStamp(strReqTimeStamp);
            long rspTimeStamp = parseTimeStamp(strRspTimeStamp);
            long delay = rspTimeStamp - reqTimeStamp;
            DelayItem delayStatData;

            if (reqTimeStamp - currRecordDate < sampleInterval * 1000) {
                delayStatData = summaryResult.get(currRecordDate);
            } else {
                currRecordDate = reqTimeStamp;
                delayStatData = new DelayItem(currRecordDate);
                delayStatData.getTotalDelay().addAndGet(delay);
                summaryResult.put(currRecordDate, delayStatData);
            }

            delayStatData.getSampleCount().incrementAndGet();
            delayStatData.getTotalDelay().addAndGet(delay);
        }
    }


    @Override
    public void process(String record) {
        String[] recordParts = filterRecord(record);
        if (null == recordParts || recordParts.length == 0){
            return;
        }
        process(recordParts);
    }

    private String[] filterRecord(String record) {
        return null;
    }

    @Override
    public Map<Long, DelayItem> getResult() {
        return null;
    }

    private long parseTimeStamp(String strRspTimeStamp) {
        return 0;
    }

    class DelayData {
        private String traceId;
        private String operationName;
        private String reqTime;
        private String rspTime;

        public DelayData() {
        }

        public String getTraceId() {
            return traceId;
        }

        public void setTraceId(String traceId) {
            this.traceId = traceId;
        }

        public String getOperationName() {
            return operationName;
        }

        public void setOperationName(String operationName) {
            this.operationName = operationName;
        }

        public String getReqTime() {
            return reqTime;
        }

        public void setReqTime(String reqTime) {
            this.reqTime = reqTime;
        }

        public String getRspTime() {
            return rspTime;
        }

        public void setRspTime(String rspTime) {
            this.rspTime = rspTime;
        }

        @Override
        public String toString() {
            return "DelayData[" +
                    "traceId='" + traceId + '\'' +
                    ", operationName='" + operationName + '\'' +
                    ", reqTime='" + reqTime + '\'' +
                    ", rspTime='" + rspTime + '\'' +
                    ']';
        }
    }
}
